﻿using Infrastructure.Access;
using Infrastructure.Extend;
using Infrastructure.Json;
using Infrastructure.Operator;
using Infrastructure.SorketOperate;
using Infrastructure.Web;
using MyData;
using MyData.Data.Repository;
using MyData.Dto;
using MyData.Models;
using MyDomain;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace MyRepository
{
    public class UserInfoRepository : RepositoryBase<UserInfo>, IUserInfoRepository
    {
        public bool SaveUserInfo(UserInfo userInfo)
        {
            using (var db = NewDB())
            {
                var model = new UserInfo();
                if (PublicInfo.Version != (int)EnumVersion.太白)
                {
                    model = db.Query<UserInfo>().FirstOrDefault(cn => cn.NickName == userInfo.NickName && cn.DepartId == cn.DepartId && cn.Id != userInfo.Id);
                }
                else
                {
                    model = db.Query<UserInfo>().FirstOrDefault(cn => cn.NickName == userInfo.NickName && cn.Id != userInfo.Id);
                }
                if (model != null)
                {
                    // throw new KnownException("用户名重复");
                    if (PublicInfo.Version != (int)EnumVersion.太白)
                    {
                        throw new KnownException("用户名重复");
                    }
                    userInfo.Id = model.Id;
                    userInfo.DepartId = model.DepartId;
                    userInfo.WorkNum = model.WorkNum;
                }

                if (userInfo.Id == Guid.Empty)
                {
                    userInfo.Id = Guid.NewGuid();
                    var mobiles = db.Query<DepartMobileRL>().Where(cn => cn.DepartId == userInfo.DepartId).Select(cn => cn.MobileId).ToList();
                    List<SyncRL> syncRLs = new List<SyncRL>();
                   
                    if (PublicInfo.Version == (int)EnumVersion.淮安)
                    {
                        #region 淮安
                        string url = "http://127.0.0.1:8080";
                        addUser addUser = new addUser()
                        {
                            commandid = "xxxxxxxxxx",
                            OidKey = userInfo.Id.ToString(),
                            base64Image = GetBase64FromImage(AppDomain.CurrentDomain.BaseDirectory + userInfo.HeadUrl),
                            deviceCode = userInfo.NickName,
                            phone = userInfo.PhoneNum
                        };
                        string result = WebClientHelper.Post(url, WebClientHelper.GetJson(addUser), "addface");
                        RuiMuDto dto = result.ToObject<RuiMuDto>();
                        if (dto.errorcode == -1)
                        {
                            throw new KnownException("添加失败");
                        }
                    }
                    else
                    {
                        foreach (var item in mobiles)
                        {
                            SyncRL syncRL = new SyncRL()
                            {
                                Id = Guid.NewGuid(),
                                UserId = userInfo.Id,
                                OperateType = (int)EnumOperateType.新增,
                                MobileId = item
                            };
                            syncRLs.Add(syncRL);
                        }
                    }
                    #endregion

                    db.InsertRange<SyncRL>(syncRLs);
                    db.Insert<UserInfo>(userInfo);
                }
                else
                {
                    var entity = db.QueryByKey<UserInfo>(userInfo.Id);
                    List<SyncRL> syncRLs = new List<SyncRL>();
                    if (entity.DepartId != userInfo.DepartId || entity.HeadUrl != userInfo.HeadUrl)
                    {
                       
                        if (PublicInfo.Version == (int)EnumVersion.淮安)
                        {
                            string url = "http://127.0.0.1:8080";
                            updateUser addUser = new updateUser()
                            {
                                commandid = "xxxxxxxxxx",
                                OidKey = userInfo.Id.ToString(),
                                deviceCode = userInfo.NickName,
                                phone = userInfo.PhoneNum,
                                base64Image = GetBase64FromImage(AppDomain.CurrentDomain.BaseDirectory + userInfo.HeadUrl)
                            };
                            string result = WebClientHelper.Post(url, WebClientHelper.GetJson(addUser), "updateface");
                            RuiMuDto dto = result.ToObject<RuiMuDto>();
                            if (dto.errorcode == -1)
                            {
                                throw new KnownException("修改失败");
                            }
                        }
                        else
                        {
                            var mobiles = db.Query<DepartMobileRL>().Where(cn => cn.DepartId == entity.DepartId).Select(cn => cn.MobileId).ToList();
                            foreach (var item in mobiles)
                            {
                                db.Delete<SyncRL>(c => c.MobileId == item && c.UserId == entity.Id);
                                SyncRL syncRL = new SyncRL()
                                {
                                    Id = Guid.NewGuid(),
                                    UserId = userInfo.Id,
                                    OperateType = (int)EnumOperateType.删除,
                                    MobileId = item
                                };
                                syncRLs.Add(syncRL);
                            }
                            var mobiles1 = db.Query<DepartMobileRL>().Where(cn => cn.DepartId == userInfo.DepartId).Select(cn => cn.MobileId).ToList();
                            foreach (var item in mobiles1)
                            {
                                db.Delete<SyncRL>(c => c.MobileId == item && c.UserId == entity.Id);
                                syncRLs.RemoveAll(c => c.MobileId == item && c.UserId == entity.Id);
                                SyncRL syncRL = new SyncRL()
                                {
                                    Id = Guid.NewGuid(),
                                    UserId = userInfo.Id,
                                    OperateType = (int)EnumOperateType.新增,
                                    MobileId = item
                                };
                                syncRLs.Add(syncRL);
                            }
                        }
                    }
                    entity.Sex = userInfo.Sex;
                    entity.WorkNum = userInfo.WorkNum;
                    entity.Age = userInfo.Age;
                    entity.NickName = userInfo.NickName;
                    entity.PhoneNum = userInfo.PhoneNum;
                    entity.Address = userInfo.Address;
                    entity.CardNum = userInfo.CardNum;
                    entity.HeadUrl = userInfo.HeadUrl;
                    entity.RoleName = userInfo.RoleName;
                    entity.Nation = userInfo.Nation;
                    entity.DepartId = userInfo.DepartId;
                    db.InsertRange<SyncRL>(syncRLs);
                    db.Update<UserInfo>(entity);
                }
                return true;

            }

        }
        /// <summary>
        /// 添加待确认的用户
        /// </summary>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public bool SaveConfirmUserInfo(UserInfo userInfo)
        {
            using (var db = this.NewDB())
            {

                var model = db.Query<UserInfo>().FirstOrDefault(cn => cn.NickName == userInfo.NickName && cn.NeedConfirm == (int)EnumNeedConfirm.是 && cn.DepartId == userInfo.DepartId);
                if (model == null)
                {
                    db.Insert<UserInfo>(userInfo);
                    return true;
                }
                else
                {
                    model.HeadUrl = userInfo.HeadUrl;
                    return db.Update<UserInfo>(model) > 0;
                }
            }
        }
        private static string GetBase64FromImage(string imagefile)
        {
            string strbaser64 = "";
            try
            {
                Bitmap bmp = new Bitmap(imagefile);
                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                strbaser64 = "data:image/jpeg;base64," + Convert.ToBase64String(arr);
            }
            catch (Exception)
            {
                throw new Exception("Something wrong during convert!");
            }
            return strbaser64;
        }
        public bool DeleteUserInfo(List<Guid> Ids)
        {
            using (var db = this.NewDB())
            {
                foreach (var id in Ids)
                {
                    var entity = db.QueryByKey<UserInfo>(id);
                    try
                    {
                        File.Delete(AppDomain.CurrentDomain.BaseDirectory + entity.HeadUrl);
                    }
                    catch (Exception)
                    {
                    }

                    var mobiles = db.Query<DepartMobileRL>().Where(c => c.DepartId == entity.DepartId).Select(c => c.MobileId).ToList();

                    if (PublicInfo.Version == (int)EnumVersion.淮安)
                    {
                        string url = "http://127.0.0.1:8080";
                        deleteUser deleteUser = new deleteUser() { commandid = "xxxxxxxxxx", group = "default_group", OidKey = id.ToString() };
                        string result = WebClientHelper.Post(url, WebClientHelper.GetJson(deleteUser), "delface");
                        RuiMuDto dto = result.ToObject<RuiMuDto>();
                        if (dto.errorcode == -1)
                        {
                            throw new KnownException("删除失败");
                        }
                    }
                    else
                    {
                        List<SyncRL> syncRLs = new List<SyncRL>();
                        foreach (var item in mobiles)
                        {
                            SyncRL syncRL = new SyncRL()
                            {
                                Id = Guid.NewGuid(),
                                UserId = entity.Id,
                                OperateType = (int)EnumOperateType.删除,
                                MobileId = item
                            };
                            syncRLs.Add(syncRL);
                        }
                        db.InsertRange<SyncRL>(syncRLs);
                    }

                    db.Delete<UserInfo>(entity);
                    db.Delete<AccessRecord>(c => c.UserId == id);
                }

                return true;
            }
        }

        public bool SynsUserSend(int command)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                var mobiles = db.IQueryable<Mobile>().Where(c => c.State == (int)EnumState.开启);
                foreach (var item in mobiles)
                {
                    try
                    {
                        SendSorket(item.Ip, item.Port, command.ToString());
                    }
                    catch (Exception ex)
                    {


                    }

                }
                return true;
            }

        }
        void SendSorket(string host, int port, string sendStr)
        {
            IPAddress ip = IPAddress.Parse(host);

            IPEndPoint ipe = new IPEndPoint(ip, port);//把ip和端口转化为IPEndPoint实例

            Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket
            c.Connect(ipe);//连接到服务器

            //string sendStr = "hello!This is a socket test";

            byte[] bs = Encoding.ASCII.GetBytes(sendStr);


            c.Send(bs, bs.Length, 0);//发送测试信息

            string recvStr = "";

            byte[] recvBytes = new byte[1024];

            int bytes;

            bytes = c.Receive(recvBytes, recvBytes.Length, 0);//从服务器端接受返回信息

            recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
            c.Close();

        }

        public bool IsExistUser(Guid departId)
        {
            using (var db = this.NewDB())
            {
                return db.Query<UserInfo>().Any(c => c.DepartId == departId);
            }
        }

        public PageDto<UserInfoDto> GetUserInfos(QueryListModel query, Guid departId, string WorkNum, string NickName, int NeedConfirm, int OrderName, int OrderType)
        {
            using (var db = this.NewDB())
            {
                var userInfos = db.Query<UserInfo>();
                if (!string.IsNullOrEmpty(WorkNum))
                {
                    userInfos = userInfos.Where(t => t.WorkNum.Contains(WorkNum));
                }
                if (!string.IsNullOrEmpty(NickName))
                {
                    userInfos = userInfos.Where(t => t.NickName.Contains(NickName));
                }
                if (departId != Guid.Parse("00000000-0000-0000-0000-000000000001"))
                {
                    userInfos = userInfos.Where(t => t.DepartId == departId);
                }
                if (NeedConfirm != 99)
                {
                    if (PublicInfo.Version != (int)EnumVersion.太白)
                    {
                        userInfos = userInfos.Where(t => t.NeedConfirm == NeedConfirm);
                    }
                    else
                    {
                        if (NeedConfirm == 0)
                        {
                            userInfos = userInfos.Where(t => !String.IsNullOrEmpty(t.HeadUrl));
                        }
                        else
                        {
                            userInfos = userInfos.Where(t => String.IsNullOrEmpty(t.HeadUrl));
                        }
                    }
                }
                if (OrderName == 0)
                {
                    if (OrderType == 0)
                    {
                        userInfos = userInfos.OrderByDesc(c => c.CreatedTime);
                    }
                    else
                    {
                        userInfos = userInfos.OrderBy(c => c.CreatedTime);
                    }
                }
                else if (OrderName == 1)
                {
                    if (OrderType == 0)
                    {
                        userInfos = userInfos.OrderByDesc(c => c.DepartId).ThenByDesc(c => c.CreatedTime);
                    }
                    else
                    {
                        userInfos = userInfos.OrderBy(c => c.DepartId).ThenByDesc(c => c.CreatedTime);
                    }
                }
                else if (OrderName == 2)
                {
                    if (OrderType == 0)
                    {
                        userInfos = userInfos.OrderByDesc(c => c.NickName).ThenByDesc(c => c.CreatedTime);
                    }
                    else
                    {
                        userInfos = userInfos.OrderBy(c => c.NickName).ThenByDesc(c => c.CreatedTime);
                    }
                }
                var departs = db.Query<Depart>().ToList();
                var linq = (from u in userInfos.ToList()
                            join
       d in departs on u.DepartId equals d.Id
                            select new UserInfoDto()
                            {
                                Id = u.Id,
                                NickName = u.NickName,
                                WorkNum = u.WorkNum,
                                RoleName = u.RoleName,
                                Sex = u.Sex,
                                Age = u.Age,
                                DepartId = u.DepartId,
                                DepartName = d.Name,
                                PhoneNum = u.PhoneNum,
                                Address = u.Address,
                                CardNum = u.CardNum,
                                HeadUrl = u.HeadUrl,
                                NeedConfirm = u.NeedConfirm,
                                CreatedTime = u.CreatedTime
                            }).AsQueryable();

                var result = linq.Paging(query.Limit, query.Offset);
                return new PageDto<UserInfoDto>()
                {
                    total = result.total,
                    rows = result.rows
                };
            }
        }

        public bool ConfirmUser(Guid Id)
        {
            using (var db = this.NewDB())
            {
                var user = db.QueryByKey<UserInfo>(Id);
                user.NeedConfirm = (int)EnumNeedConfirm.否;
                var mobiles = db.Query<DepartMobileRL>().Where(cn => cn.DepartId == user.DepartId).Select(cn => cn.MobileId).ToList();
                List<SyncRL> syncRLs = new List<SyncRL>();
                foreach (var item in mobiles)
                {
                    SyncRL syncRL = new SyncRL()
                    {
                        Id = Guid.NewGuid(),
                        UserId = user.Id,
                        OperateType = (int)EnumOperateType.新增,
                        MobileId = item
                    };
                    syncRLs.Add(syncRL);
                }
                db.InsertRange<SyncRL>(syncRLs);
                return db.Update<UserInfo>(user) > 0;
            }
        }
    }
}
